package com.icost.directive.service;

import com.icost.directive.entity.ActivationCode;
import com.icost.directive.repository.ActivationCodeRepository;
import com.icost.directive.request.BaseRequest;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
public class ActivationCodeService {
    private final ActivationCodeRepository repo;

    public ActivationCodeService(ActivationCodeRepository repo) {
        this.repo = repo;
    }

    /**
     * 校验激活码，绑定设备
     */
    @Transactional
    public boolean validateAndUse(BaseRequest baseRequest) {
        return repo.findByCodeAndUsedFalse(baseRequest.getCode()).map(c -> {
            c.setUsed(true);
            c.setProductId(baseRequest.getProductId());
            c.setUsedTime(LocalDateTime.now());
            c.setDeviceId(baseRequest.getDeviceId());
            repo.save(c);
            return true;
        }).orElseGet(() -> {
            // 如果激活码已经用过，校验设备是否一致
            return repo.findByCode(baseRequest.getCode())
                    .map(c -> baseRequest.getDeviceId().equals(c.getDeviceId())&&baseRequest.getProductId().equals(c.getProductId()))
                    .orElse(false);
        });
    }

    public String getUnusedCode() {
        return repo.findFirstByUsedFalse()
                .map(ActivationCode::getCode)
                .orElse(null);
    }

    public ActivationCode createCode(String code) {
        ActivationCode ac = new ActivationCode();
        ac.setCode(code);
        return repo.save(ac);
    }
    @Transactional
    public ActivationCode generateRandomCode(Integer productId) {
        String code;
        do {
            code = RandomStringUtils.randomAlphanumeric(6).toUpperCase(); // 6位，含数字和字母
        } while (repo.findByCode(code).isPresent()); // 保证数据库唯一

        ActivationCode ac = new ActivationCode();
        ac.setCode(code);
        ac.setProductId(productId);
        //ac.setMaxDevices(maxDevices);
        return repo.save(ac);
    }
}
